
class Store:
    def __init__(self, *args, **kwargs):
        self._model_dict = {}  # dict of Model

    def model_upload(self, model: str, files: []):
        self._model_dict[model].upload_to_ftp(files=files)
        # TODO: we should do some clear routines after upload success:
        #      1. clear model _file_info list
        #      2. reset model state
        #      ...
        #      sth like this: self._model_dict[model].reset()
        #      but we should consider if we need re-upload?

    def model_release(self, setting):
        # TODO: store must call sync_ftp_dirs in Model to sync ftp dirs to local for releasing
        # TODO: self._model_dict[model].sync_ftp_dirs() <- uncomment this for production environment!!!!!
        model_name = setting['model_name']
        self._update_model(model_name)
        for repo, br in setting['repos_info'].items():
            self._checkout_model_branch(model_name, repo, br)
        self._model_make(model_name, setting['make_type'])
        self._set_model_release_info(
            model_name,
            n_f=setting['release_info']['new_feature'],
            b_f=setting['release_info']['bug_fixed'],
            c=setting['release_info']['changed'],
            n=setting['release_info']['note'],
            ni=setting['release_info']['known_issue'],
        )

    def model_state(self, model_list):
        return [
            {
                'name': m,
                'state': self._model_dict[m].state(),
                'files': self._model_dict[m].files(),
                'log': self._model_dict[m].log(),
            }
            for m in model_list
        ]

    def _model_make(self, model: str, type_id: str):
        self._model_dict[model].make(type_id)

    def _checkout_model_branch(self, model: str,
                               repo: str, branch: str):
        self._model_dict[model].checkout_branch(repo, branch)

    def _set_model_release_info(self, model: str,
                                n_f: str = 'N/A',
                                b_f: str = 'N/A',
                                c: str = 'N/A',
                                n: str = 'N/A',
                                ni: str = 'N/A',
                                ):
        return self._model_dict[model].set_new_feature(
            n_f).set_bug_fixed(b_f).set_changed(c).set_note(n).set_known_issue(ni)

    def _sync_model_ftp_dirs(self, model):
        self._model_dict[model].sync_ftp_dirs()

    def _update_model(self, model):
        self._model_dict[model].update_all_repos()

    def push_model(self, model):
        self._model_dict.update({
            model.__str__(): model
        })

    def model_log(self, model):
        return self._model_dict[model].log()

    def model_detail_list(self, model_list):
        detail_info = []
        for m in model_list:
            if m in self._model_dict:
                self._update_model(m)
                detail_info.append(
                    self._model_dict[m].detail()
                )
        return detail_info

    def model_list(self):
        return [m for m in self._model_dict]
